1 //------------------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // Implements the interface to the application manifest
9 // 2005/05/09 - [....] Created
10 // 2007/09/20 [....] Ported Windows->DevDiv. See SourcesHistory.txt.
12 //------------------------------------------------------------------------
14 #include "PreCompiled.hxx"
15 #include "ApplicationManifest.hxx"
17 #define KEY_ASSEMBLY L"WindowsBase"
18 #define REQUESTED_CLR L"Microsoft.Windows.CommonLanguageRuntime"
21 CApplicationManifest::CApplicationManifest(__in LPCWSTR pswzUri
, __in LPCWSTR pswzCodebase
)
23 SetDeploymentManifestUri(pswzUri
);
24 SetCodebase(pswzCodebase
);
26 m_pInternetSecurityManager
= NULL
;
27 m_dwDeploymentManifestZone
= 0;
30 STDMETHODIMP
CApplicationManifest::QueryInterface(const struct _GUID
&riid
,void ** ppvObject
)
34 if (riid
== IID_IUnknown
)
36 *ppvObject
= static_cast<ISAXContentHandler
*>(this);
38 else if (riid
== __uuidof(ISAXContentHandler
))
40 *ppvObject
= static_cast<ISAXContentHandler
*>(this);
42 else if (riid
== __uuidof(IBindStatusCallback
))
44 *ppvObject
= static_cast<IBindStatusCallback
*>(this);
58 STDMETHODIMP_(DWORD
) CApplicationManifest::AddRef()
60 return InterlockedIncrement(&m_refCount
);
63 STDMETHODIMP_(DWORD
) CApplicationManifest::Release()
65 InterlockedDecrement(&m_refCount
);
77 IFACEMETHODIMP
CApplicationManifest::startElement(
78 __in_ecount(cchNamespaceUri
) const wchar_t *pwchNamespaceUri
,
79 __in
int cchNamespaceUri
,
80 __in_ecount(cchLocalName
) const wchar_t *pwchLocalName
,
81 __in
int cchLocalName
,
82 __in_ecount(cchQName
) const wchar_t *pwchQName
,
84 __in ISAXAttributes
*pAttributes
)
88 const UINT BUFFER_LENGTH
= 1024;
91 if (wcscmp(pwchLocalName
, L
"assemblyIdentity") == 0)
93 int nLength
= BUFFER_LENGTH
;
94 CKHR(pAttributes
->getValueFromName(L
"", 0, L
"name", 4, &pwzValue
, &nLength
));
95 if (wcscmp(pwzValue
, KEY_ASSEMBLY
) == 0)
97 CKHR(pAttributes
->getValueFromName(L
"", 0, L
"version", 7, &pwzValue
, &nLength
));
98 SetRequestedVersion(pwzValue
);
100 else if (wcscmp(pwzValue
, REQUESTED_CLR
) == 0)
102 CKHR(pAttributes
->getValueFromName(L
"", 0, L
"version", 7, &pwzValue
, &nLength
));
103 SetRequestedClrVersion(pwzValue
);
106 if (GetRequestedVersion() != NULL
&& GetRequestedClrVersion() != NULL
)
108 CKHR(E_FAIL
); // Stop parsing when we have both manifests
116 HRESULT
CApplicationManifest::Read()
119 ISAXXMLReader
* pReader
= NULL
;
121 // Resolve the deployment manifest URI with the application manifest codebase
122 WCHAR wzAppManUri
[INTERNET_MAX_URL_LENGTH
+ 1];
124 CKHR(CoInternetCombineUrl(
125 GetDeploymentManifestUri(),
129 INTERNET_MAX_URL_LENGTH
,
133 CKHR(SetUri(wzAppManUri
));
135 EventWriteWpfHostUm_ReadingAppManifestStart(wzAppManUri
);
137 // cocreate the pointer to the COM interface we require
138 // CLSID for internet security managed "7b8a2d94-0ac9-11d1-896c-00c04Fb6bfc4"
139 // GUID for the interface we want to extract "79eac9ee-baf9-11ce-8c82-00aa004ba90b"
140 CKHR(CoCreateInstance(CLSID_InternetSecurityManager
,
141 NULL
, CLSCTX_INPROC_SERVER
,
142 IID_IInternetSecurityManager
,
143 (void **)&m_pInternetSecurityManager
));
146 m_dwDeploymentManifestZone
= 0;
147 CKHR(m_pInternetSecurityManager
->MapUrlToZone(GetDeploymentManifestUri(), &m_dwDeploymentManifestZone
, 0));
149 DWORD dwApplicationManifestZone
= 0;
150 CKHR(m_pInternetSecurityManager
->MapUrlToZone(GetUri(), &dwApplicationManifestZone
, 0));
152 // Manifests must both come from the same zone. This is ClickOnce behavior, and we want
153 // to be consistent with it.
154 CKHR(m_dwDeploymentManifestZone
== dwApplicationManifestZone
? S_OK
: E_FAIL
);
156 // Download the file. The IBindStatusCallback::Progress method will get the new redirected URI,
157 // and do zone matching there.
158 WCHAR wzCacheFileName
[MAX_PATH
];
159 // Note: URLDownloadToCacheFile's 4th param is number of characters, not number of bytes as
160 // stated in the SDK.
161 CKHR(URLDownloadToCacheFile(NULL
, GetUri(), wzCacheFileName
, MAX_PATH
, 0, this));
163 CKHR(CoCreateInstance(__uuidof(SAXXMLReader
), NULL
, CLSCTX_INPROC_SERVER
, __uuidof(ISAXXMLReader
), (void**)&pReader
));
164 CKHR(pReader
->putContentHandler(this));
165 hr
= pReader
->parseURL(wzCacheFileName
);
167 // If we stopped the parse because we found the version, hr will be E_FAIL and
168 // the version will be set in the manifest.
169 if (hr
== E_FAIL
&& GetRequestedVersion() != NULL
)
174 EventWriteWpfHostUm_ReadingAppManifestEnd();
177 SAFERELEASE_POINTER(pReader
);
178 SAFERELEASE_POINTER(m_pInternetSecurityManager
);
183 HRESULT
CApplicationManifest::GetBindInfo(__in DWORD
*, __inout BINDINFO
* pBindInfo
)
185 //!!! Make sure to set BINDINFO_OPTIONS_ENABLE_UTF8 in all implementations of IBindStatusCallback.
186 //!!! It is needed for correct encoding of non-ASCII characters in URL paths, per RFC 3986 & 3987.
187 pBindInfo
->dwOptions
= BINDINFO_OPTIONS_ENABLE_UTF8
;
191 HRESULT
CApplicationManifest::OnProgress(ULONG ulProgress
, ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
195 if (ulStatusCode
== BINDSTATUS_REDIRECTING
)
197 SetUri(szStatusText
);
198 DWORD dwApplicationManifestZone
= 0;
199 CKHR(m_pInternetSecurityManager
->MapUrlToZone(GetUri(), &dwApplicationManifestZone
, 0));
201 // If the zones mismatch, we will stop the download immediately.
202 CKHR(m_dwDeploymentManifestZone
== dwApplicationManifestZone
? S_OK
: E_FAIL
);